home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
earcd
/
midi
/
dskchngr.lha
/
DiskChanger
/
Source
/
DiskChanger.c
next >
Wrap
C/C++ Source or Header
|
1995-08-15
|
13KB
|
559 lines
/*
as always, the source.
there are many bugs and other thingies wrong here.
this was "developed" during some work at university
and its origin is one year ago.
daniel.
*/
#define VERSION 1 // fast völlig nutzlos
#define REVISION 2
#define PREFSFILENAME "DiskChanger.prefs"
#include <exec/exec.h>
#include <dos/dos.h>
#include <devices/timer.h>
#include <rexx/storage.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/rexxsyslib.h>
#include <misc/deliplayer.h>
/* taken from the gadtoolsbox generated source */
#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/classes.h>
#include <intuition/classusr.h>
#include <intuition/imageclass.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/utility_protos.h>
#include <string.h>
#include <clib/diskfont_protos.h>
#include "gui.h"
#include <string.h>
enum { IMMEDIATE=0, LOADNOPLAY, WAITSONGEND };
#define AllocStruct(X) AllocVec(sizeof(struct X),MEMF_CLEAR|MEMF_PUBLIC)
#define FreeStruct(X) FreeVec(X)
#define CHANGESIGNAL (1L << (ULONG)changesignal)
#define DELISIGNAL (1L << DeliPort->mp_SigBit)
#define TIMESIGNAL (1L << timeport->mp_SigBit)
extern VOID DiskChangeHandler (VOID);
ULONG init_player (void);
ULONG end_player (void);
ULONG appear (void);
ULONG disappear (void);
ULONG DeliTags[] = {
DeliHeader("Diskchanger",8192,0,DELIVERSION),
DTP_Creator, (ULONG) "Daniel Balster, dbalster#amigager _ //"
"Max-Reger Weg 48, 33100 Paderborn \\X/ "
"email: dbalster@uni-paderborn.de ¯ ",
DTP_Description, (ULONG) "Lädt automatisch die entsprechende Pro"
"grammliste ein, wenn man ein Medium in"
"ein Laufwerk einlegt (oder entfernt!) ",
DTP_PlayerVersion, (VERSION<<16)|REVISION,
DTP_InitPlayer, (ULONG) init_player,
DTP_EndPlayer, (ULONG) end_player,
DTP_Appear, (ULONG) appear,
DTP_Disappear, (ULONG) disappear,
DTP_RequestKickVersion, (ULONG) 37,
TAG_DONE
};
ULONG changesignal; /* global for export */
ULONG WINDOWSIGNAL = 0; /* semaphore like used */
BOOL running = TRUE;
BOOL handler = FALSE;
BOOL waitplay = FALSE;
struct MsgPort *mp;
struct IOStdReq *ior;
struct Interrupt *irq;
/******** Prefs Settings *****************************/
UBYTE adosname [10] = { "CD0:" };
UBYTE volumename [256];
UBYTE devicename [256];
ULONG unitnumber;
UBYTE insertscript [256] = { "execute s:deliinsertdisk VOLUME %s DATABASE %s" };
UBYTE removescript [256] = { "execute s:deliinsertdisk DATABASE %s" };
UBYTE databasename [256] = { "S:Media.database" };
BOOL Popup = TRUE;
BOOL Activate = TRUE;
ULONG windowX=0, windowY=0;
UWORD InsertDelay = 150;
UWORD RemoveDelay = 800;
UWORD ProgramMode = 1;
/*******************************************************/
VOID playlist (BOOL mode)
{
UBYTE prglist[512];
UBYTE tmpbuf[512];
if(GetVar("DELIPROGRAM",prglist,512,GVF_GLOBAL_ONLY)>0)
{
if (mode)
sprintf(tmpbuf,"run <>NIL: sys:rexxc/rx \"address DELITRACKER;'clearlist';'makelist' '%s';'playlist' 1;\"",prglist);
else
sprintf(tmpbuf,"run <>NIL: sys:rexxc/rx \"address DELITRACKER;'clearlist';'makelist' '%s';\"",prglist);
Execute(tmpbuf,0,0);
}
else Execute("run <>NIL: C:RequestChoice \"Error\" \"$DELIPROGRAM was not set correct ???\" ok",0,0);
}
//
// copy a BSTR to a normal string
//
// BCPL sucks
//
VOID bstrcpy (UBYTE *a, UBYTE *b)
{
int i;
for (i=1;i<=b[0];i++) a[i-1] = b[i];
a[i-1]=0;
}
//
// get the VOLUME and DEVICE name and the unit number from an AmigaDOS device descriptor, i.e. "DF0:"
// is a valid device descriptor. there is no complex error checking yet (including user-dialog).
// if an error occurs here then install_handler will fail and the Genie is going to exit.
//
VOID getVolume (VOID)
{
struct InfoData *id;
BPTR lock;
struct DosList *dl;
if( id = AllocVec (sizeof(struct InfoData),MEMF_CLEAR|MEMF_PUBLIC))
{
if (lock = Lock (adosname,ACCESS_READ))
{
if (Info(lock,id))
{
dl = (struct DosList*)BADDR(id->id_VolumeNode);
bstrcpy(volumename,BADDR(dl->dol_Name));
}
UnLock(lock);
}
FreeVec(id);
}
}
VOID getDeviceUnit (VOID)
{
struct DosList *dl;
struct DeviceNode *dn;
struct FileSysStartupMsg *fssm;
adosname[strlen(adosname)-1]=0; // un-colon
dl = LockDosList(LDF_DEVICES|LDF_READ);
dl = FindDosEntry(dl,adosname,LDF_DEVICES|LDF_READ);
dn = (struct DeviceNode*) dl;
fssm = BADDR(dn->dn_Startup);
unitnumber = fssm->fssm_Unit;
bstrcpy(devicename,BADDR(fssm->fssm_Device));
UnLockDosList(LDF_DEVICES|LDF_READ);
adosname[strlen(adosname)]=':'; // re-colon
}
//
// install the handler. if it fails it returns FALSE
//
BOOL install_handler (STRPTR device, ULONG unit)
{
handler = FALSE;
irq = NULL;
mp = NULL;
ior = NULL;
if (!(irq=AllocStruct(Interrupt))) return FALSE;
if(!(mp=CreateMsgPort())) return FALSE;
if(!(ior=(struct IOStdReq*)CreateIORequest(mp,sizeof(struct IOStdReq)))) return FALSE;
if(OpenDevice(device,unit,ior,0)) return FALSE;
bzero(irq,sizeof(struct Interrupt));
irq->is_Code = DiskChangeHandler;
irq->is_Data = (APTR) FindTask(0);
irq->is_Node.ln_Pri = 10;
irq->is_Node.ln_Type = NT_INTERRUPT;
irq->is_Node.ln_Name = "DiskChangeHandler";
ior->io_Command = TD_ADDCHANGEINT;
ior->io_Flags = 0;
ior->io_Length = sizeof(struct Interrupt);
ior->io_Data = (APTR) irq;
SendIO(ior);
return (BOOL) (handler = ((ior->io_Error==0)?TRUE:FALSE));
}
//
// remove the handler
//
VOID remove_handler (VOID)
{
if (handler)
{
ior->io_Command = TD_REMCHANGEINT;
ior->io_Flags = 0;
ior->io_Length = sizeof(struct Interrupt);
ior->io_Data = (APTR) irq;
DoIO(ior);
CloseDevice((struct IORequest*)ior);
}
if (ior) DeleteIORequest((struct IORequest*)ior);
if (mp) DeleteMsgPort(mp);
if (irq) FreeStruct(irq);
irq = NULL;
mp = NULL;
ior = NULL;
handler = FALSE;
}
ULONG init_player (void)
{
return 0; // unused...
}
ULONG end_player (void)
{
return 0;
}
void newDevice (void)
{
remove_handler();
getDeviceUnit();
running = install_handler(devicename,unitnumber);
if (!running)
{
strcpy(adosname,"CD0:");
remove_handler();
getDeviceUnit();
running = install_handler(devicename,unitnumber);
}
}
void showAbout (void)
{
ULONG idcmp = 0;
struct EasyStruct eas;
eas.es_StructSize = sizeof(struct EasyStruct);
eas.es_Flags = NULL;
eas.es_Title = "Diskchanger V1.2";
eas.es_GadgetFormat = "Ok";
eas.es_TextFormat= " Diskchanger Genie\n"
" ©1995 by Daniel Balster\n"
" (dbalster@uni-paderborn.de)\n"
" All Rights Reserved.\n\n"
"This genie is a gift and can be used\n"
" with the DeliTracker distribution.";
EasyRequestArgs( NULL, &eas, &idcmp, 0 );
}
void savePrefs (void)
{
BPTR file;
char configdir[256]; // constant strings are shit in normal C; my generic C++ string class is much better ;-(
char filename[512];
windowX = DBWnd->LeftEdge;
windowY = DBWnd->TopEdge;
GetVar("DELICONFIG",configdir,256,GVF_GLOBAL_ONLY);
sprintf(filename,"%s/%s",configdir,PREFSFILENAME);
if(file = Open (filename,MODE_NEWFILE))
{
FPuts(file,adosname);
FPuts(file,"\n");
FPuts(file,insertscript);
FPuts(file,"\n");
FPuts(file,removescript);
FPuts(file,"\n");
FPuts(file,databasename);
FPuts(file,"\n");
FWrite(file,&(Popup),sizeof(BOOL),1);
FWrite(file,&(Activate),sizeof(BOOL),1);
FWrite(file,&(windowX),sizeof(ULONG),1);
FWrite(file,&(windowY),sizeof(ULONG),1);
FWrite(file,&(InsertDelay),sizeof(UWORD),1);
FWrite(file,&(RemoveDelay),sizeof(UWORD),1);
FWrite(file,&(ProgramMode),sizeof(UWORD),1);
Close(file);
}
}
void loadPrefs (void)
{
BPTR file;
char configdir[256];
char filename[512];
GetVar("DELICONFIG",configdir,256,GVF_GLOBAL_ONLY);
sprintf(filename,"%s/%s",configdir,PREFSFILENAME);
if(file = Open (filename,MODE_OLDFILE))
{
FGets(file,adosname,10);
adosname[strlen(adosname)-1]=0;
FGets(file,insertscript,256);
insertscript[strlen(insertscript)-1]=0;
FGets(file,removescript,256);
removescript[strlen(removescript)-1]=0;
FGets(file,databasename,256);
databasename[strlen(databasename)-1]=0;
FRead(file,&(Popup),sizeof(BOOL),1);
FRead(file,&(Activate),sizeof(BOOL),1);
FRead(file,&(windowX),sizeof(ULONG),1);
FRead(file,&(windowY),sizeof(ULONG),1);
FRead(file,&(InsertDelay),sizeof(UWORD),1);
FRead(file,&(RemoveDelay),sizeof(UWORD),1);
FRead(file,&(ProgramMode),sizeof(UWORD),1);
Close(file);
}
newDevice();
}
ULONG appear (void)
{
if (WINDOWSIGNAL) return WINDOWSIGNAL;
if (Scr = dt_LockScreen())
{
ComputeFont( 0, 0 );
if (VisualInfo = GetVisualInfo( Scr, TAG_DONE ))
{
if (!OpenDBWindow())
{
/* transfer the prefs data into the gadgets and menus */
/* ok, this is a hack ;-) */
GetString(DBGadgets[GD_Gadget70]) = adosname;
GetString(DBGadgets[GD_Gadget60]) = databasename;
GetString(DBGadgets[GD_Gadget80]) = insertscript;
GetString(DBGadgets[GD_Gadget90]) = removescript;
GT_SetGadgetAttrs(DBGadgets[GD_Gadget40],DBWnd,NULL,(GTCY_Active),(ProgramMode),(TAG_DONE));
GT_SetGadgetAttrs(DBGadgets[GD_Gadget20],DBWnd,NULL,(GTSL_Level),(InsertDelay),(TAG_DONE));
GT_SetGadgetAttrs(DBGadgets[GD_Gadget30],DBWnd,NULL,(GTSL_Level),(RemoveDelay),(TAG_DONE));
/* the menu hooks will be handled by the OpenDBWindow Function */
RefreshGadgets(DBWnd->FirstGadget,DBWnd,NULL);
WINDOWSIGNAL = (1L << DBWnd->UserPort->mp_SigBit);
}
}
}
return WINDOWSIGNAL;
}
ULONG disappear (void)
{
if (WINDOWSIGNAL)
{
windowX = DBWnd->LeftEdge;
windowY = DBWnd->TopEdge;
CloseDBWindow();
if ( VisualInfo ) {
FreeVisualInfo( VisualInfo );
VisualInfo = NULL;
}
if ( Scr ) {
dt_UnlockScreen();
Scr = NULL;
}
WINDOWSIGNAL = 0;
return -1;
}
else return 0; /* window was closed */
}
void main(void)
{
ULONG signals;
struct DeliMessage *msg;
// struct Process *proc;
// struct Window *oldptr;
struct MsgPort *timeport;
struct timerequest *timeior;
if (!(changesignal = AllocSignal(-1))) return;
// proc = FindTask(0L);
// oldptr = proc->pr_WindowPtr;
// proc->pr_WindowPtr = -1;
loadPrefs();
if (Popup) appear();
if (timeport = CreateMsgPort())
{
if (timeior = (struct timerequest*) CreateIORequest(timeport,sizeof(struct timerequest)))
{
if (!OpenDevice("timer.device",UNIT_VBLANK,timeior,0)) // a stop-clock
{
while (running)
{
signals = Wait (DELISIGNAL|SIGBREAKF_CTRL_C|CHANGESIGNAL|WINDOWSIGNAL);
if (signals & SIGBREAKF_CTRL_C) running=FALSE;
if (Activate) if (signals & CHANGESIGNAL)
{
if (handler)
{
UBYTE cmdline [512];
UBYTE cmdline2 [512];
ior->io_Command = TD_CHANGESTATE;
ior->io_Flags = IOF_QUICK;
ior->io_Length = 0;
DoIO(ior);
{
if (ior->io_Actual)
{
ULONG tmpsig;
timeior->tr_time.tv_secs = 10; // (RemoveDelay/50);
timeior->tr_node.io_Command = TR_ADDREQUEST;
timeior->tr_node.io_Flags = IOF_QUICK;
SendIO(timeior);
tmpsig = Wait (TIMESIGNAL|CHANGESIGNAL|SIGBREAKF_CTRL_C);
AbortIO(timeior);
WaitIO(timeior);
ior->io_Command = TD_CHANGESTATE;
ior->io_Flags = IOF_QUICK;
ior->io_Length = 0;
DoIO(ior);
if (ior->io_Actual)
{
sprintf(cmdline,"%s",removescript);
sprintf(cmdline2,cmdline,databasename);
Execute (cmdline2,NULL,NULL);
}
}
if (!ior->io_Actual)
{
Delay(InsertDelay);
getVolume();
sprintf(cmdline,"%s",insertscript);
sprintf(cmdline2,cmdline,volumename,databasename);
Execute (cmdline2,NULL,NULL);
}
switch (ProgramMode)
{
case IMMEDIATE:
playlist(TRUE);
break;
case LOADNOPLAY:
playlist(FALSE);
break;
case WAITSONGEND:
waitplay = TRUE;
break;
default:
break;
}
}
}
}
if (signals & WINDOWSIGNAL) /* could be zero ! */
{
running = HandleDBIDCMP();
if (running==2) disappear(); /* hide signal */
}
if (signals & DELISIGNAL)
{
if (msg = (struct DeliMessage*)GetMsg(DeliPort))
{
msg->Result = msg->Function();
ReplyMsg((struct Message*)msg);
}
}
} // while
CloseDevice(timeior);
}
DeleteIORequest((struct IORequest*)timeior);
}
DeleteMsgPort(timeport);
}
remove_handler();
disappear();
FreeSignal(changesignal);
// proc->pr_WindowPtr = oldptr;
}